﻿using DevExpress.DataAccess.ObjectBinding;
using DevExpress.XtraReports.UI;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Domain.Repositories;
using YAKEJI.Abp.Domain.Repositories;
using YAPACS.BusinessObjects.Exams;
using YAPACS.BusinessObjects.Managements.DicomClients;
using YAPACS.BusinessObjects.Managements.Exams;
using YAPACS.RisServer.Abstractions;
using YAPACS.RisServer.Services;
using YAPACS.RisServer.Services.Dtos;
using YAPACS.Workflows;

namespace YAPACS.RisServer.Controllers;
[Authorize]
public class ExamController : AbpController
{
    private readonly IExamService _examService;
    private readonly IConfiguration _configuration;
    private readonly IExamValidationService _examValidationService;
    private readonly IExamPermissionService _examPermissionService;
    private readonly IRepository<Exam, Guid> _examRepository;
    private readonly IRepository<ImageZip, Guid> _imageZipRepository;
    private readonly IRepository<ImageRelayTask, Guid> _imageRelayTaskRepository;
    private readonly IRepository<DicomClient, Guid> _dicomClientRepository;
    private readonly IRepository<ReportStyle, Guid> _reportStyleRepository;

    public ExamController(
        IConfiguration configuration,
        IExamValidationService examValidationService,
        IExamPermissionService examPermissionService,
        IRepository<Exam, Guid> examRepository,
        IRepository<ImageZip, Guid> imageRepository,
        IRepository<ImageRelayTask, Guid> imageRelayTaskRepository,
        IRepository<DicomClient, Guid> dicomClientRepository,
        IRepository<ReportStyle, Guid> reportStyleRepository,
        IExamService examService)
    {
        _configuration = configuration;
        _examValidationService = examValidationService;
        _examPermissionService = examPermissionService;
        _examRepository = examRepository;
        _imageZipRepository = imageRepository;
        _imageRelayTaskRepository = imageRelayTaskRepository;
        _dicomClientRepository = dicomClientRepository;
        _reportStyleRepository = reportStyleRepository;
        _examService = examService;
    }

    /// <summary>
    /// 验证检查
    /// </summary>
    [HttpPost]
    [Route("api/exam/validate")]
    public async Task<IActionResult> Validate(Guid examId, ExamValidationType type)
    {
        var exam = await _examRepository.GetAsync(examId);
        var result = await _examValidationService.ValidateAsync(exam, type);
        if (result.Count > 0)
        {
            return Ok(new
            {
                success = true,
                data = result.OrderBy(r => r.Key).ToDictionary(r => r.Key.ToString(), r => r.Value)
            });
        }
        return Ok(new
        {
            success = true
        });
    }
    [AllowAnonymous]
    [HttpGet("api/exam/get-dicom-client-url")]
    public Task<IActionResult> GetDicomClientUrl()
    {
        IActionResult actionResult;

        var url = _configuration.GetValue<string>("DicomClient:Url");
        if (!string.IsNullOrWhiteSpace(url))
        {
            actionResult = Ok(new
            {
                Success = true,
                Data = url
            });
        }
        else
        {
            actionResult = Ok(new
            {
                Success = false,
                Error = "没有配置DICOM图像查看器"
            });
        }

        return Task.FromResult(actionResult);
    }

    [HttpPost("api/exam/output-image")]
    public async Task<IActionResult> OutputImage([FromForm] IList<Guid> examIds, [FromForm] bool confirm)
    {
        var exams = await _examRepository.GetListAsync(e => examIds.Contains(e.Oid));
        if (exams.Count != 0)
        {
            exams.ForEach(async exam => await _examPermissionService.ValidateAsync(exam, true));

            if (exams.Any(exam => !exam.Studies.Any()))
            {
                return Ok(new
                {
                    Success = false,
                    Error = "不包含图像数据，无法导出图像"
                });
            }
            else if (exams.Any(exam => exam.ImageZip == null))
            {
                if (confirm)
                {
                    exams = exams.Where(exam => exam.ImageZip == null).ToList();
                    foreach (var exam in exams)
                    {
                        var imageZip = await _imageZipRepository.NewEntityAsync();
                        imageZip.Exam = exam;
                    }
                    return Ok(new
                    {
                        Success = true,
                        Info = "图像已加入打包任务队列，请稍后..."
                    });
                }
                else
                {
                    return Ok(new
                    {
                        Success = true,
                        Confirm = "图像尚未打包，打包后才可以下载，是否现在打包？"
                    });
                }
            }
            else
            {
                var exam = exams.First();
                if (exam.ImageZip.Status == ImageZipStatus.None)
                {
                    return Ok(new
                    {
                        Success = true,
                        Info = "图像已在打包任务队列中，请稍后..."
                    });
                }
                else if (exam.ImageZip.Status == ImageZipStatus.Zipping)
                {
                    return Ok(new
                    {
                        Success = true,
                        Info = "图像正在打包中，请稍后..."
                    });
                }
                else if (!string.IsNullOrWhiteSpace(exam.ImageZip.FileUrl))
                {
                    return Ok(new
                    {
                        Success = true,
                        Url = exam.ImageZip.FileUrl
                    });
                }
            }
            return Ok(new
            {
                Success = false,
                Error = "图像打包失败，无法导出图像"
            });
        }
        else
        {
            return Ok(new
            {
                Success = false,
                Error = "没有找到导出图像的检查"
            });
        }
    }

    [HttpPost("api/exam/relay-image")]
    public async Task<IActionResult> RelayImage([FromBody] WorkflowInput input)
    {
        var examIds = JsonConvert.DeserializeObject<IList<Guid>>(input.GetValueOrDefault("examIds").ToString() ?? "[]");
        if (examIds.Count == 0)
        {
            return Ok(new WorkflowOutput
            {
                Success = false,
                Error = "没有找到需要转发图像的检查"
            });
        }

        var dicomClientIdString = input.GetValueOrDefault("dicomClientId")?.ToString();
        if (string.IsNullOrWhiteSpace(dicomClientIdString))
        {
            var exam = await _examRepository.GetAsync(examIds[0]);
            var department = exam.Department;
            var dicomClients = department.GetDicomClients().Select(c => new { Label = c.Name, Value = c.Id, });

            return Ok(new WorkflowOutput
            {
                Success = true,
                ViewTitle = "转发图像",
                ViewWidth = "25%",
                View = await Extensions.GetResourceStringAsync("Resources.Report.send-image-view.json"),
                Data = new { DicomClients = dicomClients },
                NextApi = "/api/exam/relay-image"
            });
        }
        else
        {
            var dicomClient = await _dicomClientRepository.GetAsync(Guid.Parse(dicomClientIdString));
            var exams = await _examRepository.GetListAsync(e => examIds.Contains(e.Oid));
            var seriesList = exams.SelectMany(e => e.Studies).SelectMany(s => s.Series).ToList();

            foreach (var series in seriesList)
            {
                if (!await _imageRelayTaskRepository.AnyAsync(t => t.Series == series && t.Client == dicomClient))
                {
                    var imageRelayTask = await _imageRelayTaskRepository.NewEntityAsync();
                    imageRelayTask.Client = dicomClient;
                    imageRelayTask.Series = series;
                }
            }

            return Ok(new WorkflowOutput
            {
                Success = true
            });
        }
    }

    [AllowAnonymous]
    [HttpGet("api/exam/get-form-pdf-file")]
    public async Task<IActionResult> GetFormPdfFile([FromQuery] Guid examId, [FromQuery] ReportStyleType style)
    {
        var exam = await _examRepository.GetAsync(examId);
        var reportStyle = await _reportStyleRepository.GetAsync(e => e.IsActive && e.Department == exam.Department && e.DeviceType == exam.DeviceType && e.StyleType == style);
        if (reportStyle.Content.Length > 0)
        {
            using var stream = new MemoryStream(reportStyle.Content);
            var report = new XtraReport();
            report.LoadLayout(stream);
            report.DataSource = new ObjectDataSource { DataSource = exam };
            using var pdfStream = new MemoryStream();
            await report.ExportToPdfAsync(pdfStream);
            return File(pdfStream.GetAllBytes(), "application/pdf");
        }
        return NotFound();
    }

    /// <summary>
    /// 快速查询检查列表
    /// </summary>
    /// <param name="filterId"></param>
    /// <param name="take"></param>
    /// <param name="skip"></param>
    /// <param name="searchValue"></param>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpPost("api/exam/get-list")]
    public async Task<IActionResult> GetExamListByFilter([FromBody] DataGridRequest request, [FromQuery] string institution, [FromQuery] string applyDepartment, [FromQuery] string applyDoctor)
    {
        var result = await _examService.GetExamListByFilterAsync(request,institution,applyDepartment,applyDoctor);
        return Ok(result);
    }
    /// <summary>
    /// 获取高级搜索视图
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpGet("api/exam/get-advanced-search-view")]
    public async Task<IActionResult> GetAdvancedSearchView()
    {
        var result = await _examService.GetAdvancedSearchViewAsync();
        return Ok(result);
    }
}
